package franklin.american;

/*
 * Copyright 2001-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.util.ClassPath;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.reflections.Reflections;
import org.apache.bcel.Repository;
import org.apache.bcel.classfile.Method;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Vector;



/**
 * Goal which touches a timestamp file.
 *
 * @goal code_quality
 * 
 * @phase process-sources
 *
 */
public class MyMojo
    extends AbstractMojo
{

    int spc_count=-1;
    Vector<String> classFileList = new Vector<String>();

    /**
     * Location of the file.
     * @parameter expression="${project.build.directory}/classes"
     * @required
     */
    private File outputDirectory;

    public void execute()
        throws MojoExecutionException
    {
        File f = outputDirectory;

        /**
         * First check to see if the classes directory exist
         */
        if ( !f.exists() )
        {
            throw new MojoExecutionException("Error:  classes directory must exist! Please run compile stage");
        }
        ArrayList<File> directories = new ArrayList<File>();

        /**
         * setup new classpath
         */
        try {
        URL url = outputDirectory.toURI().toURL();
        URLClassLoader urlClassLoader = (URLClassLoader)ClassLoader.getSystemClassLoader();
        URL [] urls = urlClassLoader.getURLs();
        for (URL data: urls) {
            System.out.println("URL:"+data.toString());
        }
        URLClassLoader newClassLoader = URLClassLoader.newInstance(new URL[] {url}, urlClassLoader);
        Thread.currentThread().setContextClassLoader(newClassLoader);
        for (URL data: newClassLoader.getURLs()) {
                System.out.println("URL:"+data.toString());

        }

           Process(outputDirectory);
           System.out.println("File list is "+classFileList.size());
           String[] tmp1 = classFileList.firstElement().split("classes") ;
           System.out.println("-->"+tmp1[1]);
           String tmp2 = tmp1[1].substring(1,tmp1[1].indexOf(".class")).replaceAll("/",".");
           System.out.println("--->"+tmp2);
           JavaClass clazz = Repository.lookupClass(tmp2) ;
           Method [] meths = clazz.getMethods();
           for (Method m: meths) {
               System.out.println("==>"+m.getName()+ " <"+m.getCode().getCode().length+"> ");
           }
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
            throw new MojoExecutionException("Error: "+ex.getMessage()) ;
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (ClassNotFoundException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }


    }

    void Process(File aFile) throws IOException {
        spc_count++;
        String spcs = "";
        for (int i = 0; i < spc_count; i++)
            spcs += " ";
        if(aFile.isFile())    {
            System.out.println(spcs + "[FILE] " + aFile.getCanonicalPath());
            if (aFile.getName().endsWith(".class")) {
                this.classFileList.add(aFile.getPath()) ;
            }
        } else if (aFile.isDirectory()) {
            System.out.println(spcs + "[DIR] " + aFile.getName());
            File[] listOfFiles = aFile.listFiles();
            if(listOfFiles!=null) {
                for (int i = 0; i < listOfFiles.length; i++)
                    Process(listOfFiles[i]);
            } else {
                System.out.println(spcs + " [ACCESS DENIED]");
            }
        }
        spc_count--;
    }
}
